/*
    Space Simulation - Simulate the solar system
    Copyright (C) 2010  Guillaume Andrieu and Sylvain Martin

    This file is part of Space Simulation.

    Space Simulation is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Space Simulation is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Space Simulation.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 /*
 *Physic.c est le code source ou sont codées les fonctions et procedures qui calculent la dynamique du
 *systeme.
 *	      Gravity : calcule la force de gravité entre deux particules dans l'espace, en fonction de la 
 *			constante de gravitation.
 *	      
 *	      gravity_sum : Cette fonction contiens un algorithme qui permet de parcourir tous les couples
 *			    de particules une seule fois et d'apliquer à chaque couple le resultat du
 *			    calcul de force "Gravity" et son inverse.
 *			    (on rapelle que la force de A sur B est l'inverse de la force de B sur A)
 *			    On ajoutera chaques force agissant sur chaque particules.
 *			    A la fin de cette routine. Chaques sommes des forces de chaque particules sera
 *			    fonction de toutes les autres particules.
 *
 *	      dynamic_calculation : Cette fonction calcule a partir de la somme des forces, l'acceleration
 *				    puis la vitesse, puis la position, en utilisant le DeltaT calculé.
 */



#include "Vector3D.h"
#include "Particule.h"
#include "Simulation.h"
#include "physic.h"


Vector3D gravity(Particule par1, Particule par2, double G)
{
  Vector3D force;
  Vector3D diff = VectorSubstract(par2.position, par1.position);
  double dist = PartDistance(par1, par2);
  force = VectorScalarMul(- G * par1.mass * par2.mass / (dist*dist) , VectorUnit( diff ));
  return force;
}

void gravity_sum(Simulation * s)
{
  Vector3D TempVector;
  int i,j;
  for(i=0; i < s->particules_num; i++)
  {
    s->particules[i].force_sum = MakeVector3D(0.0, 0.0, 0.0);
  }
  for(i=0; i < s->particules_num; i++)
  {
	for(j=i+1; j < s->particules_num; j++)
	{
	TempVector = gravity(s->particules[i], s->particules[j], s->space.G);
	s->particules[i].force_sum=VectorSum(VectorScalarMul(-1.0,TempVector), s->particules[i].force_sum);	
	s->particules[j].force_sum=VectorSum(TempVector,s->particules[j].force_sum);
	}
  }
}

void dynamic_calculation(Simulation * s, double newtime)
{
  int i;
  double D_time;
  
  D_time = newtime - s->space.time;
  
  gravity_sum(s);

  for(i=0; i < s->particules_num; i++)
  {
  /* calcul de l'acceleration	*/
  s->particules[i].acceleration = VectorScalarMul(1/(s->particules[i].mass), s->particules[i].force_sum);
  /* calcul de la vitesse	*/
  s->particules[i].speed = VectorSum(s->particules[i].speed, VectorScalarMul(D_time, s->particules[i].acceleration));
  /* calcul de la position	*/
  s->particules[i].position = VectorSum(s->particules[i].position,VectorScalarMul(D_time, s->particules[i].speed));
  }
  
  s->space.time = newtime;
  
}

